//-------------------------------------------------------------------------------------
// <copyright file="ReceiveLocation.cs" company="Microsoft">
//      Copyright (c) 2003 Microsoft Corporation. All rights reserved.
//      THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 
//      EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED 
//      WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
// </copyright>
// <summary>
//      Represents a combination of a specific address where the inbound message arrives and the pipeline processes the message.
// </summary>  
//-------------------------------------------------------------------------------------

namespace Microsoft.Sdc.Tasks.BizTalk2004.Configuration
{
    using System;
    using System.Xml.Serialization;

    /// <summary>
	/// Represents a combination of a specific address where the inbound message arrives and the pipeline processes the message.
	/// </summary>
	internal class ReceiveLocation : BizTalkConfigurableEntityBase
	{
		#region Member variables 


		private string address;
		private string publicAddress;
		private bool isPrimary;
		private bool enable;

		private ReceiveHandler receiveHandler;
		private Pipeline receivePipeline;
		private ReceivePort receivePort;


		private bool endDateEnabled;
		private System.DateTime endDate;

		private bool startDateEnabled;
		private System.DateTime startDate;



		private Protocol transportType;
		private TransportData transportTypeData;
		private ServiceWindow serviceWindow = new ServiceWindow();

		#endregion 

	
		#region Properties 

		/// <summary>
		/// Gets or sets the address of the receive location.
		/// </summary>
		/// <value>A string representing the address of this receive location.</value>
		public string Address
        {
            get { return this.address; }
            set { this.address = value; }
        }
		/// <summary>
		/// Gets or sets the public address of the receive location.
		/// </summary>
		public string PublicAddress
		{

			get { return this.publicAddress; }
			set { this.publicAddress = value; }

		}

		/// <summary>
		/// Determines whether the receive location is primary.
		/// </summary>
		/// <value>boolean; true if this receive location is pirmary, false otherwise</value>
		public bool IsPrimary
		{
			get { return this.isPrimary;}
		}

		/// <summary>
		/// Gets and sets the field to enable the receive location.
		/// An enabled receive location cannot be deleted.
		/// </summary>
		public bool Enable
		{
			get { return this.enable; }
			set { this.enable = value; }
		}
       	
		
		/// <summary>
		/// Gets or sets the receive handler to use for this receive location.
		/// </summary>
		/// <value> A <see cref="Microsoft.Sdc.Tasks.BizTalk2004.Configuration.ReceiveHandler"/> object.</value>
		public ReceiveHandler ReceiveHandler
		{
			get { return this.receiveHandler; }
			set { this.receiveHandler = value; }
		}

		/// <summary>
		/// Gets or sets the receive pipeline to use to receive messages at this receive location.
		/// </summary>
		/// <value>a <see cref="Microsoft.Sdc.Tasks.BizTalk2004.Configuration.Pipeline"/> object.</value>
		public Pipeline ReceivePipeline
		{
			get { return this.receivePipeline; }
			set { this.receivePipeline = value; }
		}

		/// <summary>
		/// Gets the receive port that this receive location belongs to.
		/// </summary>
		/// <value>A <see cref="Microsoft.Sdc.Tasks.BizTalk2004.Configuration.ReceivePort"/> object.</value>
		public ReceivePort ReceivePort
		{
			get {return this.receivePort;}
		}

		
		/// <summary>
		/// Gets or sets the start date of the service window.
		/// </summary>
		public bool StartDateEnabled
		{
			get {return this.startDateEnabled;}
			set {this.startDateEnabled = value;}
		}
		/// <summary>
		/// Gets or sets the start date of the service window.
		/// </summary>
		public DateTime StartDate
		{
			get {return this.startDate;}
			set {this.startDate = value;}
		}

		/// <summary>
		/// Gets or sets the field to enable the end date of the service window.
		/// </summary>
		public bool EndDateEnabled
		{
			get {return this.endDateEnabled;}
			set {this.endDateEnabled = value;}
		}

		/// <summary>
		/// Gets or sets the end date of the service window.
		/// </summary>
		public DateTime EndDate
		{
			get {return this.endDate;}
			set {this.endDate = value;}
		}

		
		/// <summary>
        /// Gets and sets the transport type for this receive location.
        /// </summary>
        /// <value>A <see cref="Microsoft.Sdc.Tasks.BizTalk2004.Configuration.Protocol"/> object.</value>
		public Protocol TransportType
        {
            get { return this.transportType; }
            set { this.transportType = value; }
        }

		/// <summary>
		/// Gets or sets the transport type properties of the receive location.
		/// </summary>
		public TransportData TransportTypeData
		{
			get {return this.transportTypeData;}
			set {this.transportTypeData = value;}
		}

		/// <summary>
		/// Gets or sets the service window of this receive location.
		/// </summary>
		public ServiceWindow ServiceWindow
		{
			get {return this.serviceWindow;}
			set {this.serviceWindow = value;}
		}


		#endregion 

		#region Methods

		/// <summary>
		///Creates a new Receive Location instance. This is private because instance of this class can only be created with
		/// the Load method.
		/// </summary>
		/// <param name="receivePort">The <see cref="Microsoft.Sdc.Tasks.BizTalk2004.Configuration.ReceivePort"/> object that this receive location belongs to.</param>
		private ReceiveLocation(ReceivePort receivePort): base(receivePort.Installation){

			this.receivePort = receivePort;
		}

		/// <summary>
		///Creates a new Receive Location instance.
		/// </summary>
		/// <param name="receivePort">The <see cref="Microsoft.Sdc.Tasks.BizTalk2004.Configuration.ReceivePort"/> object that this receive location belongs to.</param>
		/// <param name="name">The name of this receive location</param>
		public ReceiveLocation(ReceivePort receivePort, string name): base(receivePort.Installation)
		{
			this.Name = name;
			this.receivePort = receivePort;
		}

		/// <summary>
		/// Loads the details of a Receive Location
		/// </summary>
		/// <param name="receivePort"> The <see cref="Microsoft.Sdc.Tasks.BizTalk2004.Configuration.ReceivePort"/> that this receive location belongs to.</param>
		/// <param name="name">The name of the receive location</param>
		/// <returns>A <see cref="Microsoft.Sdc.Tasks.BizTalk2004.Configuration.ReceiveLocation"/></returns>
		public static ReceiveLocation Load(ReceivePort receivePort, string name)
		{
			//check inputs
			if (receivePort == null) throw new ArgumentException("receivePort");
			if (name == null || name.Length == 0) throw new ArgumentException("name");

			//loading native type
			BtsReceiveLocation rxLocation = receivePort.Installation.CatalogExplorer.ReceivePorts[receivePort.Name].ReceiveLocations[name];

			if (rxLocation != null)
			{
				ReceiveLocation receiveLocation = new ReceiveLocation(receivePort);
				receiveLocation.Name = rxLocation.Name; 
				receiveLocation.address = rxLocation.Address;
				receiveLocation.publicAddress  =rxLocation.PublicAddress;
				receiveLocation.isPrimary = rxLocation.IsPrimary;
				receiveLocation.enable = rxLocation.Enable;

				receiveLocation.receiveHandler  = ReceiveHandler.Load(receiveLocation.Installation, rxLocation.ReceiveHandler.Name, rxLocation.ReceiveHandler.TransportType.Name);
				receiveLocation.receivePipeline = Pipeline.Load(receivePort.Installation.DeployedAssemblies[rxLocation.ReceivePipeline.BtsAssembly.DisplayName], rxLocation.ReceivePipeline.FullName); 

				receiveLocation.startDateEnabled = rxLocation.StartDateEnabled;
				receiveLocation.startDate = rxLocation.StartDate;

				receiveLocation.endDateEnabled = rxLocation.EndDateEnabled;
				receiveLocation.endDate = rxLocation.EndDate;

				receiveLocation.transportType = Protocol.Load(receivePort.Installation, rxLocation.TransportType.Name);
				
				receiveLocation.transportTypeData =  new  TransportData(rxLocation.TransportTypeData);

				receiveLocation.serviceWindow = new ServiceWindow(rxLocation.ServiceWindowEnabled, rxLocation.FromTime, rxLocation.ToTime);
				return receiveLocation;

			}
			else
				 return null;
		}

		/// <summary>
		/// Saves this receive location.
		/// </summary>
		protected internal override void SaveImpl()
		{
			//loading native type
			BtsReceiveLocation rxLocation = this.Installation.CatalogExplorer.ReceivePorts[this.receivePort.Name].ReceiveLocations[this.Name];

			if (rxLocation != null)
			{

				rxLocation.Name = this.Name;
				rxLocation.Address = this.Address;
				rxLocation.PublicAddress = this.publicAddress;
				rxLocation.Enable = this.enable;

				foreach(BtsReceiveHandler rxHandler in this.Installation.CatalogExplorer.ReceiveHandlers)
				{
					if (rxHandler.Name == this.receiveHandler.Name && 
						rxHandler.TransportType.Name == this.receiveHandler.TransportType.Name)
					{
						rxLocation.ReceiveHandler = rxHandler;
						break;
					}
				}

				rxLocation.ReceivePipeline = this.Installation.CatalogExplorer.Pipelines[this.receivePipeline.Name];

				
				rxLocation.StartDateEnabled = this.startDateEnabled;
				rxLocation.StartDate = this.startDate;
				
				rxLocation.EndDateEnabled = this.endDateEnabled;
				rxLocation.EndDate = this.endDate;
				
				rxLocation.TransportType = this.Installation.CatalogExplorer.ProtocolTypes[this.transportType.Name];
				rxLocation.TransportTypeData  = this.transportTypeData.GetTransportXml();

				rxLocation.ServiceWindowEnabled = this.serviceWindow.Enabled;
				if (this.serviceWindow.Enabled)
				{
					rxLocation.FromTime = this.serviceWindow.StartTime;
					rxLocation.ToTime = this.serviceWindow.EndTime;

				}
			}
		}

		/// <summary>
		/// Deletes a Receive Location
		/// </summary>
        /// <param name="receivePort"> A <see cref="Microsoft.Sdc.Tasks.BizTalk2004.Configuration.ReceivePort"/> to delete the Receive Location from</param>
		/// <param name="name">The name of the receive location to delete</param>
		public static void Delete(ReceivePort receivePort, string name)
		{
			BtsReceivePort actualPort = receivePort.Installation.CatalogExplorer.ReceivePorts[receivePort.Name];
			BtsReceiveLocation actualLocation = actualPort.ReceiveLocations[name];
			actualLocation.Enable = false; //disabling before deleting
			actualPort.RemoveReceiveLocation(actualLocation);

			receivePort.Installation.CatalogExplorer.SaveChanges();

		}


		/// <summary>
		/// Checks if the Receive Location  exists within BizTalk
		/// </summary>
		/// <param name="installation">
		/// The  to search in.
		/// </param>
		/// <param name="receivePort">
		/// The name of the Receive port that this receive location  belongs to.
		/// </param>
		/// <param name="name">
		/// The name of the Receive Location
		/// </param>
		/// 
		/// <returns>
		/// <b>true</b> if the Receive Port exists, or <b>false</b> otherwise.
		/// </returns>
		public static bool Exists(BizTalkInstallation installation, string receivePort, string name)
		{
			try
			{
				return installation.ReceivePorts[receivePort].ReceiveLocations[name] != null;
			}
			catch (ArgumentOutOfRangeException)
			{
				return false;
			}
		}

		#endregion
	}
}

